/*
 * @Author: AuroCaffe 18509564594@163.com
 * @Date: 2025-07-12 17:45:52
 * @LastEditors: AuroCaffe 18509564594@163.com
 * @LastEditTime: 2025-08-08 14:08:22
 * @FilePath: \HuiLin\utils\webSokent.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/*
 * @Author: AuroCaffe 18509564594@163.com
 * @Date: 2025-07-12 17:45:52
 * @LastEditors: AuroCaffe 18509564594@163.com
 * @LastEditTime: 2025-08-06 19:01:20
 * @FilePath: \HuiLin\utils\webSokent.js
 * @Description: WebSocket连接管理 - 修复版本
 */
let ws = null;
let reconnectTimer = null;
let heartbeatTimer = null;
let connectionCheckTimer = null;
let reconnectAttempts = 0;
let maxReconnectAttempts = 10;
let isConnecting = false;
let currentToken = null;
let messageCallback = null;
let lastHeartbeatTime = 0;
let heartbeatInterval = 30000; // 30秒心跳间隔
let connectionTimeout = 10000; // 10秒连接超时
let isNetworkAvailable = true;
let connectionId = null; // 添加连接ID用于多终端管理

// 生成唯一连接ID
function generateConnectionId() {
	return 'ws_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
}

// 获取WebSocket URL
function getWebSocketUrl() {
	// 根据环境返回不同的URL
	// #ifdef MP-WEIXIN
	// 微信小程序使用生产环境
	return 'wss://api.hlfe.top/socket';
	// return 'ws://192.168.3.20:8082/socket';
	// #endif

	// #ifdef H5
	// H5环境根据当前域名判断
	if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
		// 开发环境使用生产服务器，避免本地服务器问题
		return 'wss://api.hlfe.top/socket';
	} else {
		return 'wss://api.hlfe.top/socket';
	}
	// #endif

	// 默认使用生产环境
	return 'wss://api.hlfe.top/socket';
}

export function connectWS(token, onNotify) {
	// 防止重复连接
	if (isConnecting) {
		return;
	}

	// 如果已经连接且token相同，只更新回调函数
	if (ws && ws.readyState === 1 && currentToken === token) {
		messageCallback = onNotify;

		return;
	}

	// 检查token是否有效
	if (!token || typeof token !== 'string' || token.trim() === '') {
		console.error('WebSocket连接失败：无效的token');
		return;
	}

	// 检查网络状态
	if (!isNetworkAvailable) {

		setTimeout(() => connectWS(token, onNotify), 5000);
		return;
	}

	// 清理之前的连接，重连时不重置计数器
	// 只有在存在连接时才清理
	if (ws) {
		closeWS(false);
	}

	// 生成新的连接ID
	connectionId = generateConnectionId();

	isConnecting = true;
	currentToken = token;
	messageCallback = onNotify;



	// 设置连接超时
	const connectionTimeoutTimer = setTimeout(() => {
		if (isConnecting) {
			isConnecting = false;
			handleReconnect();
		}
	}, connectionTimeout);

	ws = uni.connectSocket({
		url: getWebSocketUrl(),
		success: () => {},
		fail: (err) => {
			console.error('WebSocket连接请求失败', err);
			clearTimeout(connectionTimeoutTimer);
			isConnecting = false;
			handleReconnect();
		}
	});

	ws.onOpen(() => {
		clearTimeout(connectionTimeoutTimer);
		isConnecting = false;
		reconnectAttempts = 0; // 重置重连次数
		lastHeartbeatTime = Date.now();



		// 发送认证消息，包含连接ID用于多终端管理
		try {
			const authMessage = {
				type: 'auth',
				token: token,
				connectionId: connectionId, // 添加连接ID
				timestamp: Date.now()
			};


			ws.send({
				data: JSON.stringify(authMessage)
			});

			// 启动心跳
			startHeartbeat();

			// 启动连接状态检查
			startConnectionCheck();

		} catch (error) {
			console.error('发送认证消息失败:', error);
			handleReconnect();
		}
	});

	ws.onMessage((res) => {
		try {
			const msg = JSON.parse(res.data);

			// 处理心跳响应
			if (msg.type === 'pong') {
				lastHeartbeatTime = Date.now();
				return;
			}

			// 处理认证响应
			if (msg.type === 'auth_result') {
				if (msg.success) {
					// WebSocket认证成功
				} else {
					console.error('WebSocket认证失败:', msg.message);
					handleReconnect();
				}
				return;
			}

			// 处理连接冲突（多终端登录）
			if (msg.type === 'connection_conflict') {
				uni.showToast({
					title: '您的账号在其他设备登录',
					icon: 'none',
					duration: 3000
				});
				closeWS();
				return;
			}

			if (messageCallback) messageCallback(msg);
		} catch (e) {
			console.error('WebSocket消息解析失败', e);
		}
	});

	ws.onClose((event) => {
		clearTimeout(connectionTimeoutTimer);
		isConnecting = false;
		stopHeartbeat();
		stopConnectionCheck();



		// 分析关闭原因
		if (event.code) {
			switch (event.code) {
				case 1000: // 正常关闭
					console.log('WebSocket正常关闭');
					return;
				case 1001: // 终端离开
					console.log('WebSocket终端离开');
					break;
				case 1002: // 协议错误
					console.log('WebSocket协议错误');
					break;
				case 1003: // 数据类型错误
					console.log('WebSocket数据类型错误');
					break;
				case 1006: // 异常关闭
					console.log('WebSocket异常关闭');
					break;
				case 1011: // 服务器错误
					console.log('WebSocket服务器错误');
					break;
				case 1015: // TLS握手失败
					console.log('WebSocket TLS握手失败');
					break;
				default:
					console.log('WebSocket关闭，代码:', event.code);
			}
		}

		// 如果不是主动关闭，则尝试重连
		if (currentToken && messageCallback) {
			handleReconnect();
		}
	});

	ws.onError((error) => {
		console.error('WebSocket连接错误:', error);
		clearTimeout(connectionTimeoutTimer);
		isConnecting = false;
		stopHeartbeat();
		stopConnectionCheck();

		// 检查是否是连接被拒绝的错误
		if (error.errMsg && error.errMsg.includes('Connection refused')) {
			uni.showToast({
				title: '服务器暂时不可用，请稍后重试',
				icon: 'none',
				duration: 3000
			});
			// 连接被拒绝时，延迟更长时间再重连
			setTimeout(() => {
				if (currentToken && messageCallback) {
					handleReconnect();
				}
			}, 10000);
			return;
		}

		// 检查是否是网络错误
		if (error.errMsg && (error.errMsg.includes('timeout') || error.errMsg.includes('network'))) {
			// 网络错误时，延迟重连
			setTimeout(() => {
				if (currentToken && messageCallback) {
					handleReconnect();
				}
			}, 5000);
			return;
		}

		// 只有在有token和回调的情况下才重连
		if (currentToken && messageCallback) {
			handleReconnect();
		}
	});
}

// 启动心跳机制
function startHeartbeat() {
	stopHeartbeat(); // 先停止之前的心跳

	heartbeatTimer = setInterval(() => {
		if (ws && ws.readyState === 1 && currentToken) {
			try {
				ws.send({
					data: JSON.stringify({
						type: 'ping',
						connectionId: connectionId, // 添加连接ID
						timestamp: Date.now()
					})
				});

			} catch (error) {
				console.error('发送心跳失败:', error);
				handleReconnect();
			}
		}
	}, heartbeatInterval);
}

// 停止心跳
function stopHeartbeat() {
	if (heartbeatTimer) {
		clearInterval(heartbeatTimer);
		heartbeatTimer = null;
	}
}

// 启动连接状态检查
function startConnectionCheck() {
	stopConnectionCheck(); // 先停止之前的检查

	connectionCheckTimer = setInterval(() => {
		const now = Date.now();
		const timeSinceLastHeartbeat = now - lastHeartbeatTime;

		// 如果超过心跳间隔的2倍没有收到心跳响应，认为连接异常
		if (timeSinceLastHeartbeat > heartbeatInterval * 2 && lastHeartbeatTime > 0) {
			console.log('心跳超时，重新连接');
			handleReconnect();
		}
	}, heartbeatInterval);
}

// 停止连接状态检查
function stopConnectionCheck() {
	if (connectionCheckTimer) {
		clearInterval(connectionCheckTimer);
		connectionCheckTimer = null;
	}
}

function handleReconnect() {
	// 如果重连次数超过限制，停止重连
	if (reconnectAttempts >= maxReconnectAttempts) {
		// 显示用户提示
		uni.showToast({
			title: '网络连接异常，请检查网络后重试',
			icon: 'none',
			duration: 3000
		});
		return;
	}

	// 如果当前token为空，不进行重连
	if (!currentToken) {
		return;
	}

	// 如果网络不可用，延迟重连
	if (!isNetworkAvailable) {
		setTimeout(() => handleReconnect(), 10000);
		return;
	}

	// 如果正在连接中，不重复重连
	if (isConnecting) {
		return;
	}

	reconnectAttempts++;

	// 使用指数退避算法计算延迟时间，但限制最大延迟
	const baseDelay = 2000; // 基础延迟2秒
	const maxDelay = 30000; // 最大延迟30秒
	const delay = Math.min(baseDelay * Math.pow(1.5, reconnectAttempts - 1), maxDelay);

	reconnectTimer = setTimeout(() => {
		connectWS(currentToken, messageCallback);
	}, delay);
}

export function closeWS(resetAttempts = true) {
	isConnecting = false;
	currentToken = null;
	messageCallback = null;
	connectionId = null;

	stopHeartbeat();
	stopConnectionCheck();

	if (ws) {
		try {
			// 检查WebSocket状态，只有在连接状态时才关闭
			if (ws.readyState === 1 || ws.readyState === 0) {
				ws.close();
			}
		} catch (error) {
			console.error('关闭WebSocket连接失败:', error);
		} finally {
			ws = null;
		}
	}

	if (reconnectTimer) {
		clearTimeout(reconnectTimer);
		reconnectTimer = null;
	}

	// 只有在明确要求时才重置重连计数器
	if (resetAttempts) {
		reconnectAttempts = 0;
	}
}

// 获取连接状态
export function getWSStatus() {
	return {
		isConnected: ws !== null && ws.readyState === 1,
		isConnecting: isConnecting,
		reconnectAttempts: reconnectAttempts,
		maxReconnectAttempts: maxReconnectAttempts,
		lastHeartbeatTime: lastHeartbeatTime,
		isNetworkAvailable: isNetworkAvailable,
		readyState: ws ? ws.readyState : null,
		connectionId: connectionId
	};
}

// 手动发送消息
export function sendMessage(message) {
	if (ws && ws.readyState === 1 && currentToken) {
		try {
			// 添加连接ID到消息中
			const messageWithId = {
				...message,
				connectionId: connectionId
			};

			ws.send({
				data: JSON.stringify(messageWithId)
			});
			return true;
		} catch (error) {
			console.error('发送消息失败:', error);
			return false;
		}
	}
	return false;
}

// 监听网络状态变化
export function initNetworkListener() {
	// #ifdef MP-WEIXIN
	uni.onNetworkStatusChange((res) => {
		const wasAvailable = isNetworkAvailable;
		isNetworkAvailable = res.isConnected;

		if (!wasAvailable && isNetworkAvailable) {
			// 网络恢复，尝试重连
			if (currentToken && messageCallback) {
				reconnectAttempts = 0; // 网络恢复时重置重连计数器
				setTimeout(() => {
					connectWS(currentToken, messageCallback);
				}, 2000);
			}
		} else if (wasAvailable && !isNetworkAvailable) {
			// 网络断开
		}
	});
	// #endif

	// #ifdef H5
	if (navigator.connection) {
		navigator.connection.addEventListener('change', () => {
			const wasAvailable = isNetworkAvailable;
			isNetworkAvailable = navigator.onLine;

			if (!wasAvailable && isNetworkAvailable) {
				if (currentToken && messageCallback) {
					reconnectAttempts = 0; // 网络恢复时重置重连计数器
					setTimeout(() => {
						connectWS(currentToken, messageCallback);
					}, 2000);
				}
			}
		});
	}
	// #endif
}

// 强制重连
export function forceReconnect() {
	reconnectAttempts = 0;
	if (currentToken && messageCallback) {
		closeWS(false); // 强制重连时不重置计数器，因为上面已经重置了
		setTimeout(() => {
			connectWS(currentToken, messageCallback);
		}, 1000);
	}
}

// 检查连接是否真正建立
export function isConnectionEstablished() {
	return ws !== null && ws.readyState === 1;
}

// 获取连接状态描述
export function getConnectionStatusText() {
	if (!ws) return '未连接';

	switch (ws.readyState) {
		case 0:
			return '连接中';
		case 1:
			return '已连接';
		case 2:
			return '关闭中';
		case 3:
			return '已关闭';
		default:
			return '未知状态';
	}
}

// 获取当前连接ID
export function getCurrentConnectionId() {
	return connectionId;
}

// 测试WebSocket连接（用于调试）
export function testWebSocketConnection() {
	// 调试功能已禁用
}